package src

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	. "github.com/soekchl/myUtils"
)

const (
	listDataFileFormat = dataDir + "list_%s.data"
	idxName            = "#idx"
	pathName           = "#path"
)

type dataList struct {
	Data map[string]item // NOTE 设置里的 key 对应 如果没有就不显示
}

type item struct {
	List []string
}

// NOTE 只支持一行一行 修改/删除  修改的时候单独弹窗？

// 展示列表
func getList(info *listInfo) (listStr string, max int) {
	// 读取本地数据
	data := readListFromFile(info.Path)

	// NOTE 显示标题 额外增加 idx 从 1 开始 为了方便修改
	listStr = `
	<table cellspacing="0" border="1">
		<tr align="center" style="font-weight: bold" >
		<td id="title_0">序号</td>`
	for _, v := range info.Title {
		listStr += fmt.Sprintf(`<td>%s</td>`, v.Name)
	}
	listStr += `<td>操 作</td></tr>`

	idx := 0                                     // 开始下标
	max = len(data.Data[info.Title[0].Key].List) // 结束下标
	// 内容
	for ; idx < max; idx++ {
		tmp := fmt.Sprintf(`<tr id="colume_list_%d"><td>%d</td>`, idx, idx+1)
		for _, v := range info.Title {
			value := "-"
			if len(data.Data[v.Key].List) > idx {
				value = data.Data[v.Key].List[idx]
			}
			tmp += fmt.Sprintf(`<td>%s</td>`, value)
		}
		tmp += fmt.Sprintf(`<td><input type="button" onclick="editItem(%d)" value=" 编 辑 " >`, idx)
		tmp += fmt.Sprintf(`&nbsp<input type="button" onclick="removeItem(%d)" value=" 删 除 " ></td>`, idx)
		listStr += tmp + `</tr>`
	}

	// TODO 分页 和 排序？

	listStr += "</table>"
	return
}

// 显示 新增/编辑 列表内容
func showEditList(idx int) (str string) {
	str += `<br><br>`
	for k, v := range home.List[idx].Title {
		str += fmt.Sprintf(`
	&nbsp%s : <input type="text" name="%s" id="edit_%d"><br><br>
`, v.Name, v.Key, k+1)
	}
	str += `<br>&nbsp<input type="button" onclick="saveItem()" value=" 保 存 " >`
	str += `&nbsp<input type="button" onclick="hidder()" value=" 取 消 " >`
	return
}

// 增加/修改 数据
func EditItem(c *gin.Context) {
	m := make(map[string]interface{}) // key ---> value   {"#idx":1, "#path":"test" , "test":"asdf", "name": "asdfasdf" }
	err := c.ShouldBind(&m)
	if err != nil {
		Error(err)
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	if len(m) < 1 {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "数据不能为空"})
		return
	}

	p := fmt.Sprint(m[pathName])
	data := readListFromFile(p)
	var h *listInfo
	for k, v := range home.List {
		if v.Path == p {
			h = &home.List[k]
		}
	}
	if h == nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("%s 导航栏不存在", p)})
		return
	}
	idx, _ := strconv.Atoi(fmt.Sprint(m[idxName]))

	// 修改数据
	nowMax := 0
	for _, v := range h.Title {
		l := data.Data[v.Key]
		if idx > len(l.List) {
			l.List = append(l.List, make([]string, nowMax-idx)...) // 新增 空数据
		}
		if idx == len(l.List) { // 增加
			l.List = append(l.List, fmt.Sprint(m[v.Key]))
		}
		l.List[idx] = fmt.Sprint(m[v.Key]) // 修改
		if len(l.List) > nowMax {
			nowMax = len(l.List)
		}
		data.Data[v.Key] = l
	}

	// 保存到本地
	saveJson(data, fmt.Sprintf(listDataFileFormat, p), true) // 更新保存
	c.JSON(http.StatusOK, gin.H{"message": "ok"})
}

func readListFromFile(path string) *dataList {
	buff := readFile(fmt.Sprintf(listDataFileFormat, path))
	data := &dataList{Data: make(map[string]item)}
	if len(buff) > 0 { // NOTE 有数据就解析
		err := json.Unmarshal(buff, &data)
		if err != nil {
			Errorf("读取数据错误 info=%v err=%+v", path, err)
		}
	} else {
		// NOTE 有数据库连接就从 数据库读取
		info := homeMap[path]
		if info != nil && info.SqlInfo != nil {
			conn := getSql(path)
			info := homeMap[path]
			var columns []string
			for _, v := range info.Title {
				columns = append(columns, v.Name)
			}
			list, err := conn.Select(path, columns)
			if err != nil {
				Errorf("read tableName=%s err=%v", path, err)
				return data
			}
			for _, v := range list {
				for k, vv := range v {
					tmp := data.Data[columns[k]]
					tmp.List = append(tmp.List, vv)
					data.Data[columns[k]] = tmp
				}
			}
		}
	}
	return data
}

// 删除数据
func RemoveItem(c *gin.Context) {
	m := make(map[string]interface{}) // key ---> value   {"#idx":1, "#path":"test" }
	err := c.ShouldBind(&m)
	if err != nil {
		Error(err)
		c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	if len(m) < 1 {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "数据不能为空"})
		return
	}

	p := fmt.Sprint(m[pathName])
	data := readListFromFile(p)
	var h *listInfo
	for k, v := range home.List {
		if v.Path == p {
			h = &home.List[k]
		}
	}
	if h == nil {
		c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("%s 导航栏不存在", p)})
		return
	}
	idx, _ := strconv.Atoi(fmt.Sprint(m[idxName]))

	// 删除数据
	for _, v := range h.Title {
		l := data.Data[v.Key]
		if idx == 0 {
			if len(l.List) == 1 {
				l.List = []string{}
			} else {
				l.List = l.List[1:]
			}
		} else if idx+1 == len(l.List) {
			l.List = l.List[:len(l.List)-1]
		} else {
			l.List = append(l.List[:idx], l.List[idx+1:]...)
		}
		data.Data[v.Key] = l
	}

	// 保存到本地
	saveJson(data, fmt.Sprintf(listDataFileFormat, p), true) // 更新保存
	c.JSON(http.StatusOK, gin.H{"message": "ok"})
}
